
// Copyright (C) Recursion Company. All rights reserved.

#include "stdafx.h"
#include "vol_user_app_info.h"

//-----------------------------------------------------------------------------------------

#include <direct.h>

CVWnd_DriveBox::CVWnd_DriveBox ()
{
    m_chCurrentDrive = '\0';
    m_npMatchDriveType = 0;
    m_clrText = RGB (0, 0, 0);
    m_clrBack = RGB (255, 255, 255);

    m_brhBack.CreateSolidBrush (GetRealBackColor (m_clrBack));
}

BOOL CVWnd_DriveBox::CreateControl (CVolNativeWndCreateParam* pCreateParam)
{
    pCreateParam->m_dwStyle |= CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL;

    if (_CREATE_WND_BY_PARAM (pCreateParam) != NULL)
    {
        init ();
        return TRUE;
    }

    return FALSE;
}

LRESULT CVWnd_DriveBox::OnKillfocus (UINT uNotifyCode, int nID, CWindow wndCtl)
{
    SendKillFocusNativeMessage (m_hWnd, m_pEventListener);
    return 0;
}

LRESULT CVWnd_DriveBox::OnSetfocus (UINT uNotifyCode, int nID, CWindow wndCtl)
{
    SendSetFocusNativeMessage (m_hWnd, m_pEventListener);
    return 0;
}

LRESULT CVWnd_DriveBox::OnSelendok (UINT uNotifyCode, int nID, CWindow wndCtl)
{
    const INT_P npCurSel = GetCurSel ();

    if (npCurSel == CB_ERR)
        m_chCurrentDrive = '\0';
    else
        m_chCurrentDrive = (TCHAR)GetItemData ((INT)npCurSel);

    if (m_pEventListener != NULL)
        m_pEventListener->OnDriveChanged ();

    return 0;
}

HBRUSH CVWnd_DriveBox::OnReflectedCtlColor (CDCHandle dc, CWindow wnd, INT nCtlType)
{
    dc.SetTextColor (m_clrText);
    dc.SetBkColor (GetRealBackColor (m_clrBack));

    return m_brhBack;
}

void CVWnd_DriveBox::SetBackColor (COLORREF clrBack)
{
    if (m_clrBack != clrBack)
    {
        m_clrBack = clrBack;
        if (m_brhBack.m_hBrush != NULL)
            m_brhBack.DeleteObject ();
        m_brhBack.CreateSolidBrush (GetRealBackColor (m_clrBack));

        if (m_hWnd != NULL)
            Invalidate ();
    }
}

TCHAR CVWnd_DriveBox::GetCurrentDriveChar () const
{
    return (m_chCurrentDrive == '\0' ? (_getdrive () + 'A' - 1) : m_chCurrentDrive);
}

CVolString CVWnd_DriveBox::GetCurrentDrive () const
{
    TCHAR cary [2];
    cary [0] = GetCurrentDriveChar ();
    cary [1] = '\0';

    return CVolString (cary);
}

void CVWnd_DriveBox::SetCurrentDrive (const TCHAR* szDrive)
{
    m_chCurrentDrive = ToUpperCase (szDrive [0]);

    if (m_hWnd == NULL)
        return;

    const TCHAR chDrive = GetCurrentDriveChar ();

    const INT_P npCount = GetCount ();
    INT_P npIndex = 0;
    for (; npIndex < npCount; npIndex++)
    {
        if ((TCHAR)GetItemData ((INT)npIndex) == chDrive)
            break;
    }

    if (npIndex < npCount)
    {
        SetCurSel ((INT)npIndex);
        m_chCurrentDrive = chDrive;
    }
    else
    {
        SetCurSel (-1);
        m_chCurrentDrive = '\0';
    }
}

void CVWnd_DriveBox::SetMatchDriveType (const INT_P npMatchDriveType)
{
    m_npMatchDriveType = CLIP (npMatchDriveType, 0, 5);
    init ();
}

void CVWnd_DriveBox::init ()
{
    if (m_hWnd == NULL)
        return;

    ResetContent ();

    TCHAR buf [MAX_PATH];
    buf [0] = '\0';
    GetLogicalDriveStrings (NUM_ELEMENTS_OF (buf) - 1, buf);

    TCHAR caryDrive [3];
    caryDrive [0] = ' ';
    caryDrive [1] = ':';
    caryDrive [2] = '\0';

    TCHAR caryDriveType [4];
    caryDriveType [0] = '\0';
    caryDriveType [1] = ':';
    caryDriveType [2] = OS_PATH_CHAR;
    caryDriveType [3] = '\0';

    const TCHAR chCurDrive = GetCurrentDriveChar ();
    INT_P npCurSel = -1;

    const TCHAR* ps = buf;
    while (*ps != '\0')
    {
        caryDriveType [0] = caryDrive [0] = ToUpperCase (*ps);
        
        const INT_P npDriveType = (INT_P)GetDriveType (caryDriveType);

        if (m_npMatchDriveType == 0 ||
                (m_npMatchDriveType == 1 && npDriveType == DRIVE_REMOVABLE) ||
                (m_npMatchDriveType == 2 && npDriveType == DRIVE_FIXED) ||
                (m_npMatchDriveType == 3 && npDriveType == DRIVE_CDROM) ||
                (m_npMatchDriveType == 4 && npDriveType == DRIVE_REMOTE) ||
                (m_npMatchDriveType == 5 && npDriveType == DRIVE_RAMDISK))
        {
            CVolString strCaption (caryDrive);

            switch (npDriveType)
            {
            case DRIVE_FIXED:
                strCaption.AddText (_T_NAME_DRIVE_FIXED);
                break;
            case DRIVE_CDROM:
                strCaption.AddText (_T_NAME_DRIVE_CDROM);
                break;
            case DRIVE_REMOTE:
                strCaption.AddText (_T_NAME_DRIVE_REMOTE);
                break;
            case DRIVE_RAMDISK:
                strCaption.AddText (_T_NAME_DRIVE_RAMDISK);
                break;
            }

            if (npDriveType == DRIVE_FIXED)
            {
                TCHAR caryVol [256];
                caryVol [0] = ' ';

                if (GetVolumeInformation (ps, &caryVol [1], NUM_ELEMENTS_OF (caryVol) - 2, NULL, NULL, NULL, NULL, NULL) &&
                        caryVol [1] != '\0')
                {
                    strCaption.AddText (caryVol);
                }
            }

            const INT_P npItemIndex = AddString (strCaption.GetText ());
            if (chCurDrive == caryDrive [0])
                npCurSel = npItemIndex;
            SetItemData ((INT)npItemIndex, (DWORD)caryDrive [0]);
        }

        ps += _tcslen (buf) + 1;
    }

    if (npCurSel == -1)
    {
        m_chCurrentDrive = '\0';
        SetCurSel (-1);
    }
    else
    {
        m_chCurrentDrive = chCurDrive;
        SetCurSel ((INT)npCurSel);
    }
}
